package leetcode_1501_1600;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class LeeCode_1595_2 {
    public static void main(String[] args) {
        List<List<Integer>> cost = new ArrayList<>();
        List<Integer> c1 = new ArrayList<>();
        c1.add(15);
        c1.add(96);
        List<Integer> c2 = new ArrayList<>();
        c2.add(36);
        c2.add(2);
        cost.add(c1);
        cost.add(c2);
        System.out.println(connectTwoGroups(cost));
//        List<List<Integer>> cost = new ArrayList<>();
//        List<Integer> c1 = new ArrayList<>();
//        c1.add(1);
//        List<Integer> c2 = new ArrayList<>();
//        c2.add(1);
//        cost.add(c1);
//        cost.add(c2);
//        System.out.println(connectTwoGroups(cost));
    }

    private static int connectTwoGroups(List<List<Integer>> cost) {
        int n = cost.size(), m = cost.get(0).size();
        int[] minCost = new int[m];
        Arrays.fill(minCost, Integer.MAX_VALUE);
        for (int j = 0; j < m; j++) {
            for (List<Integer> c : cost) {
                minCost[j] = Math.min(minCost[j], c.get(j));
            }
        }
        int[][] memo = new int[n][1 << m];
        for (int i = 0; i < n; i++) {
            Arrays.fill(memo[i], -1);
        }
        return dfs(n - 1, (1 << m) - 1, minCost, cost, memo);
    }
    private static int dfs(int i, int j, int[] minCost, List<List<Integer>> cost, int[][] memo){
        int m = cost.get(0).size();
        if (i < 0){
            if (j == 0)
                return 0;
            int res = 0;
            for (int k = 0; k < m; k++) {
                if ((j & (1 << k)) != 0){
                    res += minCost[k];
                }
            }
            return res;
        }
        if (memo[i][j] != -1){
            return memo[i][j];
        }
        int res = Integer.MAX_VALUE;
        for (int k = 0; k < m; k++) {
            res = Math.min(res, dfs(i - 1, (j & (1 << k)) == 0 ? j : j ^ (1 << k), minCost, cost, memo) + cost.get(i).get(k));
        }
        memo[i][j] = res;
        return res;
    }
}